package toubiao.utils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.crypto.Data;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import toubiao.domain.excel.ProjectGrid4Excel;
import toubiao.domain.po.business.PoContact;
import toubiao.domain.po.business.PoContract;
import toubiao.domain.po.business.PoContractPhoto;
import toubiao.domain.po.business.PoDepartment;
import toubiao.domain.po.business.PoDesigner;
import toubiao.domain.po.business.PoPartA;
import toubiao.domain.po.business.PoProject;
import toubiao.domain.po.business.PoProjectSn;
import toubiao.domain.vo.business.ContractGrid;
import toubiao.domain.vo.business.ContractPhoto;
import toubiao.domain.vo.business.ProjectDetail;
import toubiao.domain.vo.business.ProjectGrid;
import utils.UtilCollection;
import utils.UtilString;

public class ProUtilPoConvert {
static private Logger logger=LoggerFactory.getLogger(ProUtilPoConvert.class);
	
	static public <S,T> T convertRoute(Class<S> sourceClass,Class<T> targetClass,S s) throws InstantiationException, IllegalAccessException{
		if(s==null){
			return null;
		}
		T t=null;
		
		// PoProject 转换
		if(sourceClass.getSimpleName().equalsIgnoreCase("PoProject")){
			PoProject sourceBeanFlag=new PoProject();
			PoProject source=(PoProject) s;
			if(targetClass.getSimpleName().equalsIgnoreCase("ProjectGrid4Excel")){
				ProjectGrid4Excel targetBeanFlag=new ProjectGrid4Excel();
				t=(T) getVo(sourceBeanFlag,targetBeanFlag,source);
				return t;
			}
			if(targetClass.getSimpleName().equalsIgnoreCase("ProjectGrid")){
				ProjectGrid targetBeanFlag=new ProjectGrid();
				t=(T) getVo(sourceBeanFlag,targetBeanFlag,source);
				return t;
			}
			if(targetClass.getSimpleName().equalsIgnoreCase("ProjectDetail")){
				ProjectDetail targetBeanFlag=new ProjectDetail();
				t=(T)getVo(sourceBeanFlag, targetBeanFlag, source);
			}
		}
		
		// PoContract 转换
		if(sourceClass.getSimpleName().equalsIgnoreCase("PoContract")){
			PoContract sourceBeanFlag=new PoContract();
			PoContract source=(PoContract) s;
			if(targetClass.getSimpleName().equalsIgnoreCase("contractGrid")){
				ContractGrid targetBeanFlag=new ContractGrid();
				t=(T) getVo(sourceBeanFlag,targetBeanFlag,source);
				return t;
			}
		}
		
		// PoContractPhoto 转换
		if(sourceClass.getSimpleName().equalsIgnoreCase("PoContractPhoto")){
			PoContractPhoto sourceBeanFlag=new PoContractPhoto();
			PoContractPhoto source=(PoContractPhoto) s;
			if(targetClass.getSimpleName().equalsIgnoreCase("ContractPhoto")){
				ContractPhoto targetBeanFlag=new ContractPhoto();
				t=(T) getVo(sourceBeanFlag,targetBeanFlag,source);
				return t;
			}
		}
		
		return t;
	}
	


	static public <S,T> List<T> getList(Class<S> sourceClass,Class<T> targetClass,Collection<S> sCollection) throws InstantiationException, IllegalAccessException{
		List<T> tList=new ArrayList<>();
		for(S s:sCollection){
			T t=convertRoute(sourceClass, targetClass, s);
			tList.add(t);
		}
		return tList;
	}
	
	private static ProjectDetail getVo(PoProject sourceBeanFlag,
			ProjectDetail targetBeanFlag, PoProject project){
		if(project==null){
			return null;
		}
		ProjectDetail projectDetail=new ProjectDetail();
		BeanUtils.copyProperties(project, projectDetail);
		
		String projectSns=getProjectSns(project);
		projectDetail.setSns(projectSns);
		
		Date beginDate=project.getBeginDate();
		if(beginDate!=null){
			Calendar calendar=Calendar.getInstance();
			calendar.setTime(beginDate);
			projectDetail.setYear(calendar.get(Calendar.YEAR));
		}
		
		Set<PoContract> contractSet=project.getContractSet();
		Map<String, Object> contractMap=getContractMap(contractSet);
		projectDetail.setContractIds((String) contractMap.get("contractIds"));
		projectDetail.setContractSns((String) contractMap.get("contractSns"));
		projectDetail.setContractAmount((Double) contractMap.get("contractAmount"));
		
		PoPartA partA=project.getPartA();
		logger.info(partA+"");
		Map<String, Object> partAMap=getPartAMap(partA);
		projectDetail.setPartAId((Long)partAMap.get("partAId"));
		projectDetail.setPartAName((String)partAMap.get("partAName"));
		projectDetail.setPartAType((String)partAMap.get("partAType"));
		
		Set<PoContact> contactSet=project.getContactSet();
		Map<String, Object> contactMap=getContactMap(contactSet);
		projectDetail.setContactIds((String)contactMap.get("contactIds"));
		projectDetail.setContactNames((String)contactMap.get("contactNames"));
		projectDetail.setContactPhones((String)contactMap.get("contactPhones"));
		
		Set<PoDepartment> departmentSet=project.getDepartmentSet();
		logger.info(departmentSet.size()+"");
		Map<String, Object> departmentMap=getDepartmentMap(departmentSet);
		projectDetail.setDepartmentIds((String) departmentMap.get("departmentIds"));
		projectDetail.setDepartmentNames((String)departmentMap.get("departmentNames"));
		
		Set<PoDesigner> designerSet=project.getDesignerSet();
		logger.info(designerSet.size()+"");
		Map<String, Object> designerMap=getDesignerMap(designerSet);
		projectDetail.setDesignerIds((String) designerMap.get("designerIds"));
		projectDetail.setDesignerNames((String) designerMap.get("designerNames"));
		projectDetail.setDesignerPhones((String) designerMap.get("designerPhones"));
		
		return projectDetail;
	}
	
	
	private static ProjectGrid getVo(PoProject sourceBeanFlag,
			ProjectGrid targetBeanFlag, PoProject project) {
		if(project==null){
			return null;
		}
		ProjectGrid projectGrid=new ProjectGrid();
		BeanUtils.copyProperties(project, projectGrid);
		
		
		String sns=getProjectSns(project);
		projectGrid.setSns(sns);
		
		Set<PoContract> contractSet=project.getContractSet();
		Map<String, Object> projectContractMap=getContractMap(contractSet);
		projectGrid.setContractIds((String) projectContractMap.get("contractIds"));
		projectGrid.setContractSns((String) projectContractMap.get("contractSns"));
		projectGrid.setContractAmount((Double) projectContractMap.get("contractAmount"));
		
		PoPartA partA=project.getPartA();
		Map<String, Object> partAMap=getPartAMap(partA);
		projectGrid.setPartAId((Long) partAMap.get("partAId"));
		projectGrid.setPartAName((String) partAMap.get("partAName"));
		projectGrid.setPartAType((String) partAMap.get("partAType"));
		
		

		return projectGrid;
	}

	
	
	static public ProjectGrid4Excel getVo(PoProject sourceTypeFlag,ProjectGrid4Excel targetTypeFlag,PoProject project){
		if(project==null){
			return null;
		}
		ProjectGrid4Excel excelProject=new ProjectGrid4Excel();
		BeanUtils.copyProperties(project, excelProject);
		
		
		excelProject.setSns(getProjectSns(project));
		
		Set<PoContract> contractSet=project.getContractSet();
		Map<String, Object> projectContractMap=getContractMap(contractSet);
		excelProject.setContractSns((String) projectContractMap.get("contractSns"));
		excelProject.setContractAmount((Double) projectContractMap.get("contractAmount"));
		
		PoPartA partA=project.getPartA();
		Map<String, Object> partAMap=getPartAMap(partA);
		excelProject.setPartAName((String) partAMap.get("partAName"));
		excelProject.setPartAType((String) partAMap.get("partAType"));
		
		return excelProject;
	}
	
	
	static public ContractGrid getVo(PoContract sourceTypeFlag,ContractGrid targetTypeFlag,PoContract poContract){
		if(poContract==null){
			return null;
		}
		ContractGrid contractGrid=new ContractGrid();
		
		BeanUtils.copyProperties(poContract, contractGrid);
		
		Set<PoProject> projectSet=poContract.getProjectSet();
		Map<String, Object> projectMap=getProjectMap(projectSet);
		contractGrid.setProjectIds((String) projectMap.get("projectIds"));
		contractGrid.setProjectSns((String) projectMap.get("projectSns"));
		contractGrid.setProjectInvestAmount((Double) projectMap.get("projectInvestAmout"));
		
		PoPartA partA=poContract.getEntrustPartA();
		Map<String, Object> partAMap=getPartAMap(partA);
		contractGrid.setPartAId((Long) partAMap.get("partAId"));
		contractGrid.setPartAName((String) partAMap.get("partAName"));
		contractGrid.setPartAType((String) partAMap.get("partAType"));

		Set<PoContact> contactSet=poContract.getContactSet();
		Map<String,Object> contactMap=getContactMap(contactSet);
		contractGrid.setContactNamesAndPhones((String) contactMap.get("contactNameAndPhones"));
		
		return contractGrid;
	}
	
	private static ContractPhoto getVo(PoContractPhoto sourceBeanFlag,
			ContractPhoto targetBeanFlag, PoContractPhoto source) {
		// TODO Auto-generated method stub
		if(source==null){
			return null;
		}
		ContractPhoto contractPhoto=new ContractPhoto();
		BeanUtils.copyProperties(source, contractPhoto);
		PoContract contract=source.getContract();
		if(contract!=null){
			contractPhoto.setContractSn(contract.getSn());
			contractPhoto.setContractName(contract.getName());
			contractPhoto.setContractId(contract.getId());
		}
		
		return contractPhoto;
	}
	
	 static private String getProjectSns(PoProject project){
		Set<PoProjectSn> snSet=project.getSnSet();
		/*logger.info("id = "+project.getId());
		logger.info(snSet.size()+"");*/
		String sns="";
		
		List<Integer> snList=new ArrayList<>();
		if(!UtilCollection.isNullOrEmpty(snSet)){
			for(PoProjectSn sn:snSet){
				Integer integer=new Integer(-1);
				
				if(sn==null || sn.getSnInt()==null){
				}else {
					integer=sn.getSnInt();
				}
				snList.add(integer);
				logger.info(sns);
			}
			sns=UtilCollection.numberList2String(snList, "asc", ProConstant.STRING_DIVIDOR);
			logger.info(sns);
		}
		return sns;
	}
	 
	static private Map<String, Object> getContractMap(Collection<PoContract> contractCollection){
		Map<String, Object> map=new HashMap<String, Object>();
		
		String contractIds="";
		String contractSns="";
		String contractNames="";
		Double contractAmount=0D;
		
		map.put("contractIds", contractIds);
		map.put("contractSns", contractSns);
		map.put("contractNames", contractNames);
		map.put("contractAmount", contractAmount);
		
		
		if(!UtilCollection.isNullOrEmpty(contractCollection)){
			for(PoContract contract:contractCollection){
				contractIds+=contract.getId()+ProConstant.STRING_DIVIDOR;
				
				if(contract.getName()==null){
					contractNames+=ProConstant.STRING_DIVIDOR;
				}else{
					contractNames+=contract.getName()+ProConstant.STRING_DIVIDOR;
				}
				
				if(contract.getSn()==null){
					contractSns+=ProConstant.STRING_DIVIDOR;
				}else {
					contractSns+=contract.getSn()+ProConstant.STRING_DIVIDOR;
				}
				contractAmount+=contract.getAmount();
			}
			contractIds=UtilString.deleteTail(contractIds, ProConstant.STRING_DIVIDOR.length());
			contractNames=UtilString.deleteTail(contractNames, ProConstant.STRING_DIVIDOR.length());
			contractSns=UtilString.deleteTail(contractSns, ProConstant.STRING_DIVIDOR.length());
			
			map.put("contractIds", contractIds);
			map.put("contractSns", contractSns);
			map.put("contractNames", contractNames);
			map.put("contractAmount", contractAmount);
		}
		
		return map;
	}
	
	static  private Map<String, Object> getProjectMap(Collection<PoProject> projectCollection){
		Map<String, Object> projectMap=new HashMap<>();
		String projectIds="";
		String projectSns="";
		String projectNames="";
		Double projectInvestAmount=0D;
		
		if(!UtilCollection.isNullOrEmpty(projectCollection)){
			StringBuilder projectIdsStringBuilder=new StringBuilder();
			StringBuilder projectSnsStringBuilder=new StringBuilder();
			StringBuilder projectNamesStringBuilder=new StringBuilder();
			for(PoProject poProject:projectCollection){
				projectIdsStringBuilder.append(poProject.getId()).append(ProConstant.STRING_DIVIDOR);
				
				if(poProject.getName()!=null){
					projectNamesStringBuilder.append(poProject.getName()).append(ProConstant.STRING_DIVIDOR);
				}else {
					projectNamesStringBuilder.append(ProConstant.STRING_DIVIDOR);
				}
				
				if(!UtilCollection.isNullOrEmpty(poProject.getSnSet())){
					Set<PoProjectSn> snSet=poProject.getSnSet();
					StringBuilder sns=new StringBuilder();
					for(PoProjectSn sn:snSet){
						if(sn.getSnInt()==null){
							sns.append(ProConstant.STRING_DIVIDOR);
						}else {
							sns.append(sn.getSnInt()+ProConstant.STRING_DIVIDOR);
						}
					}
					String snsString=UtilString.deleteTail(sns.toString(), ProConstant.STRING_DIVIDOR.length());
					projectSnsStringBuilder.append(snsString).append(";");
				}else {
					projectSnsStringBuilder.append(";");
				}
				
				if(poProject.getInvestAmount()!=null){
					projectInvestAmount+=poProject.getInvestAmount();
				}
			}
			
			projectIds=UtilString.deleteTail(projectIdsStringBuilder.toString(), ProConstant.STRING_DIVIDOR.length());
			projectSns=UtilString.deleteTail(projectSnsStringBuilder.toString(), ";".length());
			projectNames=UtilString.deleteTail(projectNamesStringBuilder.toString(), ProConstant.STRING_DIVIDOR.length());
		}
		projectMap.put("projectIds", projectIds);
		projectMap.put("projectSns", projectSns);
		projectMap.put("projectNames", projectNames);
		projectMap.put("projectInvestAmount", projectInvestAmount);
		
		return projectMap;
	}
	
	private static Map<String, Object> getPartAMap(PoPartA poPartA){
		Long partAId=null;
		String partAName="";
		String partAType="";
		
		Map<String, Object> map=new HashMap<>();
		if(poPartA!=null){
			partAId=poPartA.getId();
			if(poPartA.getName()!=null){
				partAName=poPartA.getName();
				partAType=poPartA.getType();
			}
		}
		map.put("partAId", partAId);
		map.put("partAName", partAName);
		map.put("partAType", partAType);
		
		return map;
	}
	
	private static Map<String, Object> getContactMap(Collection<PoContact> contactCollection){
		Map<String, Object> map=new HashMap<>();
		String contactIds="";
		String contactNames="";
		String contactPhones="";
		String contactNameAndPhones="";
		
		if(!UtilCollection.isNullOrEmpty(contactCollection)){
			StringBuilder contactIdsSb=new StringBuilder();
			StringBuilder contactNamesSb=new StringBuilder();
			StringBuilder contactPhonesSb=new StringBuilder();
			StringBuilder contactNameAndPhoneSb=new StringBuilder();
			for(PoContact poContact:contactCollection){
				contactIdsSb.append(poContact.getId()).append(ProConstant.STRING_DIVIDOR);
				
				if(poContact.getName()==null){
					contactNameAndPhoneSb.append("xxx");
					contactNamesSb.append(ProConstant.STRING_DIVIDOR);
				}else {
					contactNameAndPhoneSb.append(poContact.getName());
					contactNamesSb.append(poContact.getName()).append(ProConstant.STRING_DIVIDOR);
				}
				contactNameAndPhoneSb.append(":");
				
				if(poContact.getPhone()==null){
					contactNameAndPhoneSb.append("xxx");
					contactPhonesSb.append(ProConstant.STRING_DIVIDOR);
				}else {
					contactNameAndPhoneSb.append(poContact.getPhone());
					contactPhonesSb.append(poContact.getPhone()).append(ProConstant.STRING_DIVIDOR);
				}
				contactNameAndPhoneSb.append(ProConstant.STRING_DIVIDOR);
			}
			
			contactIds=UtilString.deleteTail(contactIdsSb.toString(), ProConstant.STRING_DIVIDOR.length());
			contactNames=UtilString.deleteTail(contactNamesSb.toString(), ProConstant.STRING_DIVIDOR.length());
			contactPhones=UtilString.deleteTail(contactPhonesSb.toString(), ProConstant.STRING_DIVIDOR.length());
			contactNameAndPhones=UtilString.deleteTail(contactNameAndPhoneSb.toString(), ProConstant.STRING_DIVIDOR.length());
		}
		
		map.put("contactIds", contactIds);
		map.put("contactNames", contactNames);
		map.put("contactPhones", contactPhones);
		map.put("contactNamesAndPhones", contactNameAndPhones);
		return map;
	}
	
	static public Map<String, Object> getDepartmentMap(Collection<PoDepartment> departmentCollection){
		Map<String, Object> map=new HashMap<>();
		String departmentIds=null;
		String departmentNames="";
		
		if(!UtilCollection.isNullOrEmpty(departmentCollection)){
			StringBuilder departmentIdsSb=new StringBuilder();
			StringBuilder departmentNamesSb=new StringBuilder();
			for(PoDepartment department:departmentCollection){
				departmentIdsSb.append(department.getId()).append(ProConstant.STRING_DIVIDOR);
				if(department.getName()!=null){
					departmentNamesSb.append(department.getName()).append(ProConstant.STRING_DIVIDOR);
				}
			}
			departmentIds=UtilString.deleteTail(departmentIdsSb.toString(), ProConstant.STRING_DIVIDOR.length());
			departmentNames=UtilString.deleteTail(departmentNamesSb.toString(), ProConstant.STRING_DIVIDOR.length());
		}
		map.put("departmentIds", departmentIds);
		map.put("departmentNames", departmentNames);
		return map;
	}
	
	public static Map<String,Object> getDesignerMap(Collection<PoDesigner> designers){
		Map<String, Object> map=new HashMap<>();
		String designerIds="";
		String designerNames="";
		String designerPhones="";
		String designerNameAndPhones="";
		
		if(!UtilCollection.isNullOrEmpty(designers)){
			StringBuilder designerIdsSb=new StringBuilder();
			StringBuilder designerNamesSb=new StringBuilder();
			StringBuilder designerPhonesSb=new StringBuilder();
			StringBuilder designerNameAndPhoneSb=new StringBuilder();
			for(PoDesigner podesigner:designers){
				designerIdsSb.append(podesigner.getId()).append(ProConstant.STRING_DIVIDOR);
				
				if(podesigner.getName()==null){
					designerNameAndPhoneSb.append("xxx");
					designerNamesSb.append(ProConstant.STRING_DIVIDOR);
				}else {
					designerNameAndPhoneSb.append(podesigner.getName());
					designerNamesSb.append(podesigner.getName()).append(ProConstant.STRING_DIVIDOR);
				}
				designerNameAndPhoneSb.append(":");
				
				if(podesigner.getPhone()==null){
					designerNameAndPhoneSb.append("xxx");
					designerPhonesSb.append(ProConstant.STRING_DIVIDOR);
				}else {
					designerNameAndPhoneSb.append(podesigner.getPhone());
					designerPhonesSb.append(podesigner.getPhone()).append(ProConstant.STRING_DIVIDOR);
				}
				designerNameAndPhoneSb.append(ProConstant.STRING_DIVIDOR);
			}
			
			designerIds=UtilString.deleteTail(designerIdsSb.toString(), ProConstant.STRING_DIVIDOR.length());
			designerNames=UtilString.deleteTail(designerNamesSb.toString(), ProConstant.STRING_DIVIDOR.length());
			designerPhones=UtilString.deleteTail(designerPhonesSb.toString(), ProConstant.STRING_DIVIDOR.length());
			designerNameAndPhones=UtilString.deleteTail(designerNameAndPhoneSb.toString(), ProConstant.STRING_DIVIDOR.length());
		}
		
		map.put("designerIds", designerIds);
		map.put("designerNames", designerNames);
		map.put("designerPhones", designerPhones);
		map.put("designerNamesAndPhones", designerNameAndPhones);
		logger.info(map+"");
		return map;
	}
	
}
